#pragma once

#include "glare.core.Prerequisites.h"

namespace Glare {

	template<class T>
	class Factory
	{
#if GLARE_CXX_11_FEATURES_ENABLED
		typedef std::map<std::string, std::function<T*()>> CreatorMap;

		public : void RegisterFactory(const string& name, std::function<T*()> create_lambda)
		{
			_creators.insert(std::make_pair(name, create_lambda));
		}

		public : void UnregisterFactory(const string& name)
		{
			_creators.erase(name);
		}

		public : T* Create(const string& name)
		{
			CreatorMap::iterator it = _creators.find(name);

			if(it != _creators.end())
				return it->second();

			return NULL;
		}

		public : std::vector<string> GetKeys()
		{
			std::vector<string> list;

			std::for_each(_creators.begin(), _creators.end(), [&list](CreatorMap::value_type& kv)
			{
				list.push_back(kv.first);
			});

			return list;
		}

		private : CreatorMap _creators;
#endif
	};

}